package com.yl.order.model;

import com.yl.common.utils.LogUtil;
import com.yl.order.App;
import com.yl.order.Constants;
import com.yl.order.db.DbManage;
import com.yl.order.db.entity.OrderEntity;
import com.yl.order.db.entity.OrderGoodsEntity;
import com.yl.order.db.OrderEntityDao;
import com.yl.order.db.OrderGoodsEntityDao;

import org.greenrobot.greendao.query.QueryBuilder;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
import java.util.stream.Collectors;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * create by cjx on 2024/4/21
 * desc:
 */
public class OrderModel {
    public OrderModel() {

    }

    public static OrderEntity getOrderByNo(String orderNo) {
        return DbManage.getInstance().getDaoSession().getOrderEntityDao()
                .queryBuilder()
                .where(OrderEntityDao.Properties.OrderNo.eq(orderNo))
                .unique();
    }

    public static synchronized void getOrderGoods(int status, int offset, int limit, boolean desc, Consumer<ArrayList<OrderGoodsEntity>> onNext) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        long time = calendar.getTimeInMillis();
        Disposable subscribe = Observable.create((ObservableOnSubscribe<ArrayList<OrderGoodsEntity>>) emitter -> {
                    OrderGoodsEntityDao dao = DbManage.getInstance().getDaoSession().getOrderGoodsEntityDao();
                    QueryBuilder<OrderGoodsEntity> builder = dao.queryBuilder()
                            .where(OrderGoodsEntityDao.Properties.MakeStatus.eq(status))
                            .where(OrderGoodsEntityDao.Properties.UpdateTimeStamp.ge(time))
                            .offset(offset)
                            .limit(limit);
                    if (desc) {
                        builder.orderDesc(OrderGoodsEntityDao.Properties.UpdateTimeStamp);
                    } else {
                        builder.orderAsc(OrderGoodsEntityDao.Properties.UpdateTimeStamp);
                    }
                    List<OrderGoodsEntity> list = builder
                            .build()
                            .list();
                    emitter.onNext(new ArrayList<>(list));
                    emitter.onComplete();
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(onNext);
    }

    public static void saveOrder(OrderEntity order, List<OrderGoodsEntity> orderGoods) {
        if (order == null || orderGoods == null) {
            return;
        }
        LogUtil.getInstance().log("SQL",
                "保存订单：" + order.getOrderNo());
        DbManage.getInstance().getDaoSession().getOrderEntityDao().save(order);

        for (OrderGoodsEntity g : orderGoods) {
            g.setOrderNo(order.getOrderNo());
            g.setUpdateTime(order.getCreateTime());
            try {
                g.setUpdateTimeStamp(Constants.DATE_TIME_FORMAT.parse(order.getCreateTime()).getTime());
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
        DbManage.getInstance().getDaoSession().getOrderGoodsEntityDao().saveInTx(orderGoods);
    }

    public static void initTodaySerialNumber() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        OrderEntity unique = DbManage.getInstance().getDaoSession().getOrderEntityDao()
                .queryBuilder()
                .where(OrderEntityDao.Properties.CreateTimestamp.ge(c.getTime().getTime()))
                .orderDesc(OrderEntityDao.Properties.CreateTimestamp)
                .limit(1)
                .unique();
        if (unique == null) {
            App.app.serialNumber = 1;
        } else {
            App.app.serialNumber = unique.getSerialNo() + 1;
        }
    }

    public static List<OrderEntity> getOrderInOrderNo(Object[] orderNoArray) {
        return DbManage.getInstance().getDaoSession().getOrderEntityDao()
                .queryBuilder()
                .where(OrderEntityDao.Properties.OrderNo.in(orderNoArray))
                .list();
    }

    public static long getOrderGoodsCount(int status) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        long time = calendar.getTimeInMillis();

        return DbManage.getInstance().getDaoSession().getOrderGoodsEntityDao()
                .queryBuilder()
                .where(OrderGoodsEntityDao.Properties.MakeStatus.eq(status))
                .where(OrderGoodsEntityDao.Properties.UpdateTimeStamp.ge(time))
                .count();
    }

    public static boolean checkValidOrderNumber(String orderId) {
        long count = DbManage.getInstance().getDaoSession().getOrderEntityDao()
                .queryBuilder()
                .where(OrderEntityDao.Properties.OrderNo.eq(orderId))
                .count();
        return count == 0;
    }

    public static void deleteHistory(long lastTime) {
        OrderEntityDao orderEntityDao = DbManage.getInstance().getDaoSession().getOrderEntityDao();
        List<OrderEntity> orderList = orderEntityDao.queryBuilder()
                .where(OrderEntityDao.Properties.CreateTimestamp.lt(lastTime))
                .list();
        if (orderList.isEmpty()) {
            return;
        }
        orderEntityDao.deleteInTx(orderList);

        OrderGoodsEntityDao orderGoodsEntityDao = DbManage.getInstance().getDaoSession().getOrderGoodsEntityDao();
        List<String> orderNoList = new ArrayList<>(orderList.size());
        for (OrderEntity entity : orderList) {
            orderNoList.add(entity.getOrderNo());
        }
        orderGoodsEntityDao.queryBuilder()
                .where(OrderGoodsEntityDao.Properties.OrderNo.in(orderNoList))
                .buildDelete().executeDeleteWithoutDetachingEntities();
    }

    public static long getOrderCount(int status) {
        return DbManage.getInstance().getDaoSession()
                .getOrderGoodsEntityDao()
                .queryBuilder()
                .where(OrderGoodsEntityDao.Properties.MakeStatus.eq(status))
                .count();
    }
}
